//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.cloudfast.common.sm2;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 加密 使用 框架组的代码
 *
 * @author liuyw
 * @date 2022年9月2日
 */
public class Sm2Encryptor {
    private static final Logger log = LoggerFactory.getLogger(Sm2Encryptor.class);

    public Sm2Encryptor() {
    }

    public String decryptString(String privateKeyStr, String encryptText) throws InvalidCipherTextException {
        ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
                new BigInteger(ByteUtils.fromHexString(privateKeyStr)), Sm2Util.DOMAIN_PARAMS);
        byte[] decryptedData = Sm2Util.decrypt(priKey, fromHexString(encryptText));
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    public static String publicEncrypt(String data, String publicKeyStr) throws InvalidCipherTextException {
        String publicXandY = publicKeyStr.substring(2, publicKeyStr.length());
        int selfLen = publicXandY.length() / 2;
        int len = publicXandY.length();
        String xHex = publicXandY.substring(0, selfLen);
        String yHex = publicXandY.substring(selfLen, len);
        ECPublicKeyParameters pubKey = BcecUtil.createEcPublicKeyParameters(xHex, yHex, Sm2Util.CURVE,
                Sm2Util.DOMAIN_PARAMS);
        byte[] encryptedData = Sm2Util.encrypt(pubKey, data.getBytes());
        return ByteUtils.toHexString(encryptedData);
    }

    public static String privateDecrypt(String data, String privateKeyStr) throws InvalidCipherTextException {
        ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(new BigInteger(HexUtils.hexToByte(privateKeyStr)),
                Sm2Util.DOMAIN_PARAMS);
        byte[] decryptedData = Sm2Util.decrypt(priKey, HexUtils.hexToByte(data));
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    public String encryptString(String data, String publicKeyStr) throws InvalidCipherTextException {
        String publicXandY = publicKeyStr.substring(2, publicKeyStr.length());
        int selfLen = publicXandY.length() / 2;
        int len = publicXandY.length();
        String xHex = publicXandY.substring(0, selfLen);
        String yHex = publicXandY.substring(selfLen, len);
        ECPublicKeyParameters pubKey = BcecUtil.createEcPublicKeyParameters(xHex, yHex, Sm2Util.CURVE,
                Sm2Util.DOMAIN_PARAMS);
        byte[] encryptedData = Sm2Util.encrypt(pubKey, data.getBytes());
        return ByteUtils.toHexString(encryptedData);
    }

    public void generateKey() {
        AsymmetricCipherKeyPair keyPair = Sm2Util.generateKeyPairParameter();
        ECPrivateKeyParameters priKey = (ECPrivateKeyParameters) keyPair.getPrivate();
        ECPublicKeyParameters pubKey = (ECPublicKeyParameters) keyPair.getPublic();
        String privateKey = ByteUtils.toHexString(priKey.getD().toByteArray()).toUpperCase();
        String publicKey = ByteUtils.toHexString(pubKey.getQ().getEncoded(false)).toUpperCase();
        log.info("SM2公钥，请配置在cloudfast.security.public-key: {}", publicKey);
        log.info("SM2私钥，请配置在cloudfast.security.private-key: : {}", privateKey);
    }

    public static byte[] fromHexString(String hexString) {
        if (null != hexString && !"".equals(hexString.trim())) {
            byte[] bytes = new byte[hexString.length() / 2];
            int two = 2;

            for (int i = 0; i < hexString.length() / two; ++i) {
                String hex = hexString.substring(i * 2, i * 2 + 2);
                bytes[i] = (byte) Integer.parseInt(hex, 16);
            }

            return bytes;
        } else {
            return new byte[0];
        }
    }
}
